package com.xinchao.common.util;

import java.util.HashMap;
import java.util.Map;
import java.util.Random;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.xinchao.common.constant.CmccApiConstant;
import com.xinchao.common.constant.DateFormatConstant;
import com.xinchao.common.exception.CmccApiException;

/**
 * 调用中国移动接口工具类(详细请参考移动文档《物联云能力开放平台服务接口协议V3.0》)
 * 调用成功后，要用DESUtils工具类对返回结果进行解密
 *
 * @author dxy
 * @date 2018/8/16 9:27
 */
public class CmccApiUtils {
	private static Logger logger = LoggerFactory.getLogger(CmccApiUtils.class);
	/**
	 * 访问中国移动接口URL地址
	 */
	public static final String BASE_URL = "http://120.197.89.173:8081/openapi/router";
	/**
	 * appKey
	 * 应用键，开放平台用以确定客户端应用的身份，应用键对应一个密钥 secret。
	 * 要基于服务平台开发应用，必须事先通过申请获取 appKey/secret 后，才能进行应用的开发。
	 * 可登陆物联云平台获取appKey/secrect。
	 * 值由中国移动提供
	 */
	public static final String KEY_APPKEY = "appKey";

//	public static final String VALUE_APPKE = "6610mmrbzm";
	/**
	 * 服务方法名，一般采用“名词+动词”的结构定义
	 */
	public static final String KEY_METHOD = "method";
	/**
	 * 本次版本为3.0
	 */
	public static final String KEY_V = "v";
	public static final String VALUE_V = "3.0";
	/**
	 * 通信报文格式，可选值为 xml 和 json，此处选择json
	 */
	public static final String KEY_FORMAT = "format";
	public static final String VALUE_FORMAT = "json";
	/**
	 * 签名串，请求参数的签名，服务平台通过它验证请求数据的合法性。本系统使用中国移动提供的ApiUtils工具类
	 * 加密参数构成请参见《物联云能力开放平台服务接口协议V3.0》的3.3.3.4 签名(sign)算法
	 */
	public static final String KEY_SIGN = "sign";
	/**
	 * 报文流水号，一共31位，构成：10位集团编码+17位到毫秒的时间戳+4位随机数字
	 */
	public static final String KEY_TRANSID = "transID";
	/**
	 * 加密密钥，由中国移动提供
	 */
//	public static final String SECRECT = "6770453c2bba52ad9f2a0bf24d5806b9";
	/**
	 * 10位集团编码，由中国移动提供
	 */
//	public static final String GROUP_CODE = "2004932306";
	/**
	 * 参数iccids(多个)
	 */
	public static final String KEY_ICCIDS = "iccids";

	/**
	 * 参数iccid(单个)
	 */
	public static final String KEY_ICCID = "iccid";
	/**
	 * 号码key（单个）
	 */
	public static final String KEY_MSSIDN = "mssidn";
	/**
	 * 号码key(多个)
	 */
	public static final String KEY_MSSIDNS = "mssidns";
	/**
	 * 操作类型key
	 */
	public static final String KEY_OPT_TYPE = "optType";

	/**
	 * 操作类型key
	 */
	public static final String KEY_MONTH = "month";

	/**
	 * 调用中国移动接口
	 *
	 * @param method 服务方法名（调用不同的接口有不同的方法名，具体请参考《物联云能力开放平台服务接口协议V3.0》文档）
	 * @param iccids iccid字符串（以逗号隔开）<iccid: 集成电路卡识别码即SIM卡卡号，相当于手机号码的身份证>
	 * @param multi 是否多个
	 * @param month 月份（可以为空，格式为yyyyMM）
	 * @param appKeyValue 应用键值
	 * @param secrect 密钥
	 * @param groupCode 集团编码
	 * @return String（json字符串）
	 */

	public static String bachQuery(String method, String iccids, Boolean multi, String month, String appKeyValue, String secrect, String groupCode) throws CmccApiException {
		if (StringUtils.isBlank(method) || StringUtils.isBlank(iccids) || multi == null
				|| StringUtils.isBlank(appKeyValue) || StringUtils.isBlank(secrect)) {
			throw new NullPointerException("输入参数为空");
		}
		//17位毫秒时间戳
		String timeStamp = DateUtils.longTimeStampToStringDate(System.currentTimeMillis(), DateFormatConstant.DATE_MINUTES_24_MILLISECOND);
		//4位随机数
		Random random = new Random();
		int num = 1000 + random.nextInt(9000);
		//报文流水号，一共31位，构成：10位集团编码+17位到毫秒的时间戳+4位随机数字，例：2009999999201705161835221230001
		String transID = groupCode + timeStamp + num;
		//签名参数构成元素MAP
		Map<String, String> signMap = new HashMap<>();
		//参数列表
		Map<String, Object> parameter = new HashMap<>();

		signMap.put(KEY_APPKEY, appKeyValue);
		signMap.put(KEY_METHOD, method);
		signMap.put(KEY_V, VALUE_V);
		signMap.put(KEY_FORMAT, VALUE_FORMAT);
		signMap.put(KEY_TRANSID, transID);
		if (multi) {
			signMap.put(KEY_ICCIDS, iccids);
		} else {
			signMap.put(KEY_ICCID, iccids);
		}
		//月份
		if (StringUtils.isNotBlank(month)) {
			signMap.put(KEY_MONTH, month);
		}

		parameter.put(KEY_APPKEY, appKeyValue);
		parameter.put(KEY_METHOD, method);
		parameter.put(KEY_V, VALUE_V);
		parameter.put(KEY_FORMAT, VALUE_FORMAT);
		parameter.put(KEY_TRANSID, transID);
		if (multi) {
			parameter.put(KEY_ICCIDS, iccids);
		} else {
			parameter.put(KEY_ICCID, iccids);
		}
		//月份
		if (StringUtils.isNotBlank(month)) {
			parameter.put(KEY_MONTH, month);
		}

		//签名串，请求参数的签名，服务平台通过它验证请求数据的合法性。
		String sign = ApiUtils.sign(signMap, null, secrect);
		parameter.put(KEY_SIGN, sign);
		//调用移动接口
		String result = RestClientUtils.post(BASE_URL, parameter);
		//加密key为平台所分配的secret前面24个字符
		String desKey = secrect.substring(0, 24);
		//3DES解密
		String decryptResult = DESUtils.decrypt(result, desKey);

		JSONObject resultJsonObj = JSON.parseObject(decryptResult);
		int code = resultJsonObj.getIntValue(CmccApiConstant.CMCC_RESPONSE_CODE);
		if (code != 0) {
			throw new CmccApiException(resultJsonObj.getString(CmccApiConstant.CMCC_RESPONSE_ERROR));
		}
		String data = resultJsonObj.getString(CmccApiConstant.CMCC_RESPONSE_DATA);

		logger.debug("--------------------------------------------------");
		logger.debug("result: " + result);
		logger.debug("baseURL: " + BASE_URL);
		logger.debug("desKey: " + desKey);
		logger.debug("appKey: " + appKeyValue);
		logger.debug("method: " + method);
		logger.debug("v: " + VALUE_V);
		logger.debug("format: " + VALUE_FORMAT);
		logger.debug("transID: " + transID);
		logger.debug("sign: " + sign);
		logger.debug("iccids: " + iccids);
		logger.debug("parameter: " + parameter.toString());
		logger.debug("after_decryptResult: " + decryptResult);
		logger.debug("data: " + data);
		logger.debug("--------------------------------------------------");
		return data;
	}

	/**
	 * 开停sim
	 * @param method 服务方法名（调用不同的接口有不同的方法名，具体请参考《物联云能力开放平台服务接口协议V3.0》文档）
	 * @param msisdns 号码
	 * @param multi 是否多个
	 * @param optTpye 操作类型（1：停；2：开）
	 * @param appKeyValue 应用键值
	 * @param secrect 密钥
	 * @param groupCode 集团编码
	 * @return String
	 */
	public static String switchSim(String method, String msisdns, Boolean multi, Integer optTpye, String appKeyValue, String secrect, String groupCode) {
		if (StringUtils.isBlank(method) || StringUtils.isBlank(msisdns) || multi == null || optTpye == null
				|| StringUtils.isBlank(appKeyValue) || StringUtils.isBlank(secrect)) {
			throw new NullPointerException("输入参数为空");
		}
		//17位毫秒时间戳
		String timeStamp = DateUtils.longTimeStampToStringDate(System.currentTimeMillis(), DateFormatConstant.DATE_MINUTES_24_MILLISECOND);
		//4位随机数
		Random random = new Random();
		int num = 1000 + random.nextInt(9000);
		//报文流水号，一共31位，构成：10位集团编码+17位到毫秒的时间戳+4位随机数字，例：2009999999201705161835221230001
		String transID = groupCode + timeStamp + num;
		//签名参数构成元素MAP
		Map<String, String> signMap = new HashMap<>();
		//参数列表
		Map<String, Object> parameter = new HashMap<>();

		signMap.put(KEY_APPKEY, appKeyValue);
		signMap.put(KEY_METHOD, method);
		signMap.put(KEY_V, VALUE_V);
		signMap.put(KEY_FORMAT, VALUE_FORMAT);
		signMap.put(KEY_TRANSID, transID);
		if (multi) {
			signMap.put(KEY_MSSIDNS, msisdns);
		} else {
			signMap.put(KEY_MSSIDN, msisdns);
		}

		String strOptType = String.valueOf(optTpye);
		signMap.put(KEY_OPT_TYPE, strOptType);

		parameter.put(KEY_APPKEY, appKeyValue);
		parameter.put(KEY_METHOD, method);
		parameter.put(KEY_V, VALUE_V);
		parameter.put(KEY_FORMAT, VALUE_FORMAT);
		parameter.put(KEY_TRANSID, transID);
		parameter.put(KEY_OPT_TYPE, strOptType);
		if (multi) {
			parameter.put(KEY_MSSIDNS, msisdns);
		} else {
			parameter.put(KEY_MSSIDN, msisdns);
		}

		//签名串，请求参数的签名，服务平台通过它验证请求数据的合法性。
		String sign = ApiUtils.sign(signMap, null, secrect);
		parameter.put(KEY_SIGN, sign);
		//调用移动接口
		String result = RestClientUtils.post(BASE_URL, parameter);
		//加密key为平台所分配的secret前面24个字符
		String desKey = secrect.substring(0, 24);
		//3DES解密
		String decryptResult = DESUtils.decrypt(result, desKey);
		return decryptResult;
	}


}
